home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DTP
/
DTP_TEX
/
3238.ZIP
/
DVIEPS2.ZIP
/
DVIEPS.C
< prev
next >
Wrap
Text File
|
1988-11-01
|
22KB
|
711 lines
/*=======================================================================
* Program : DVIEPS.C
* Purpose : TeX device driver
* Date : Oct 1988
*========================================================================
* Compiler : Microsoft V5.1 C Compiler
* Linker : Microsoft V3.61 Linker
* Enviroment : MS-DOS 3.21
*========================================================================
* Edit History
*
* / / -gbm-
*
*======================================================================*/
#include "dvidefs.h"
#define extern
#include "dvivars.h"
#undef extern
/***********************************************************************
Magnification table for 144dpi, 200dpi, and 300dpi devices, computed
to 20 figures and sorted by magnitude.
Column 1 Column 2 Column 3
0.72*sqrt(1.2)**i sqrt(1.2)**I 1.5*sqrt(1.2)**I (I = -16,16)
***********************************************************************/
double mag_table[] =
{
0.16744898601451165028, 0.18343117374303022733, 0.20093878321741398034,
0.22011740849163627280, 0.23256803936137783874, 0.24112653986089677641,
0.25476552262595201888, 0.26414089018996352736, 0.27908164723365340649,
0.28935184783307613169, 0.30571862715114242265, 0.31696906822795623283,
0.33489797668038408779, 0.34722221739969135802, 0.34885205904206675812,
0.36686235258137090718, 0.38036288187354747940, 0.38214828393892802832,
0.40187757201646090535, 0.41666666087962962963, 0.41862247085048010974,
0.44023482309764508862, 0.45643545824825697527, 0.45857794072671363398,
0.48225308641975308642, 0.49999999305555555556, 0.50234696502057613169,
0.52828178771717410634, 0.54772254989790837033, 0.55029352887205636077,
0.57870370370370370370, 0.59999999166666666667, 0.60281635802469135802,
0.63393814526060892761, 0.65726705987749004440, 0.66035223464646763293,
0.69444444444444444444, 0.71999999000000000000, 0.72337962962962962963,
0.76072577431273071313, 0.78872047185298805327, 0.79242268157576115952,
0.83333333333333333333, 0.86399998800000000000, 0.86805555555555555556,
0.91287092917527685576, 0.94646456622358566393, 0.95090721789091339142,
1.00000000000000000000, 1.03679998560000000000, 1.04166666666666666670,
1.09544511501033222690, 1.13575747946830279670, 1.14108866146909606970,
1.20000000000000000000, 1.24415998272000000000, 1.25000000000000000000,
1.31453413801239867230, 1.36290897536196335610, 1.36930639376291528360,
1.44000000000000000000, 1.49299197926400000000, 1.50000000000000000000,
1.57744096561487840680, 1.63549077043435602730, 1.64316767251549834040,
1.72800000000000000000, 1.79159037511680000000, 1.80000000000000000000,
1.89292915873785408810, 1.96258892452122723270, 1.97180120701859800840,
2.07360000000000000000, 2.14990845014016000000, 2.16000000000000000000,
2.27151499048542490570, 2.35510670942547267930, 2.36616144842231761010,
2.48832000000000000000, 2.57989014016819200000, 2.59200000000000000000,
2.72581798858250988690, 2.82612805131056721510, 2.83939373810678113220,
2.98598400000000000000, 3.09586816820183040000, 3.11040000000000000000,
3.27098158629901186430, 3.40727248572813735860, 3.58318080000000000000,
3.73248000000000000000, 3.92517790355881423710, 4.08872698287376483030,
4.29981696000000000000, 4.47897600000000000000, 4.90647237944851779640,
5.37477120000000000000, 5.88776685533822135560, 6.44972544000000000000
};
int main(int argc, char **argv)
{
register int k; /* loop index */
register int file_args; /* count of file arguments */
(void)strcpy(g_progname, argv[0]); /* save program name */
(void)initglob(); /* do this before argc check! */
if (argc < 2)
{
(void)usage(stderr);
(void)exit(1);
}
for (k = 1; k < argc; ++k)
{
if (*argv[k] == '-') /* -switch */
(void)option(argv[k]);
}
if (!quiet)
{
(void)fprintf(stderr,"[TeX82 DVI Translator Version %s]",VERSION_NO);
NEWLINE(stderr);
(void)fprintf(stderr,"[%s]",DEVICE_ID);
NEWLINE(stderr);
}
if (npage == 0) /* no page ranges given, make a large one */
{
page_begin[0] = 1;
page_end[0] = 32767; /* arbitrary large integer */
page_step[0] = 1;
npage = 1;
}
else /* need font defs from postamble if only some pages to be output */
preload = TRUE;
file_args = 0;
for (k = 1; k < argc; ++k)
{
if (*argv[k] != '-') /* must be file argument */
{
file_args++;
(void)dvifile(argc,argv,argv[k]);
}
}
(void)alldone(); /* this will never return */
return (0); /* never executed; avoid compiler warnings */
}
/*******************************************************************
This routine is called on both success and failure to terminate
execution. All open files (except stdin, stdout, stderr) are closed
before calling EXIT() to quit.
*******************************************************************/
void abortrun(code)
int code;
{
unsigned int k;
char *tcp;
char fname[100];
for (k = 0; k < (unsigned int)nopen; ++k)
if (font_files[k].font_id != (FILE*)NULL)
(void)fclose(font_files[k].font_id);
if (dvifp != (FILE*)NULL)
(void)fclose(dvifp);
if (plotfp != (FILE*)NULL)
(void)fclose(plotfp);
if (g_dolog && (g_logfp != (FILE *)NULL))
(void)fclose(g_logfp);
close(bmap_file);
if ((tcp = getenv("EPSBMAP")) == (char *)NULL)
strcpy(fname, "BMAP.TMP");
else
strcpy(fname, tcp);
unlink(fname);
(void)exit(code);
}
void alldone()
{
register int t;
if ((g_errenc != 0) && g_dolog && (g_logfp != (FILE *)NULL))
{ /* errors occurred - copy log file to stderr */
(void)fflush(g_logfp); /* make sure file is up-to-date */
(void)rewind(g_logfp); /* rewind it */
while ((t=(int)getc(g_logfp)) != EOF) /* copy to stderr */
(void)putc((char)t,stderr);
(void)fclose(g_logfp); /* close it */
g_logfp = (FILE *)NULL;
}
abortrun(g_errenc);
}
/* This used to be a long in-line macro, but some compilers could not */
/* handle it. */
void dbgopen(fp, fname, openmode)
FILE* fp; /* file pointer */
char* fname; /* file name */
char* openmode; /* open mode flags */
{
if (DBGOPT(DBG_OKAY_OPEN) && (fp != (FILE *)NULL))
{
(void)fprintf(stderr,"%%Open [%s] mode [%s]--[OK]",fname,openmode);
NEWLINE(stderr);
}
if (DBGOPT(DBG_FAIL_OPEN) && (fp == (FILE *)NULL))
{
(void)fprintf(stderr,"%%Open [%s] mode [%s]--[FAILED]",fname,openmode);
NEWLINE(stderr);
}
}
void devinit(argc, argv) /* initialize device */
int argc;
char *argv[];
{
(void)getbmap();
if (runlengthcode && !quiet)
{
(void)fprintf(stderr, "[Run-length encoding of output file]");
NEWLINE(stderr);
}
}
void devterm() /* terminate device */
{
}
void fatal(msg) /* issue a fatal error message */
char *msg; /* message string */
{
if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
{
g_logfp = fopen(g_logname,"w+");
DEBUG_OPEN(g_logfp,g_logname,"w+");
if (g_logfp == (FILE *)NULL)
{
(void)fprintf(stderr,"Cannot open log file [%s]",g_logname);
NEWLINE(stderr);
}
else
{
(void)fprintf(stderr,"[Log file [%s] created]",g_logname);
NEWLINE(stderr);
}
}
if (g_dolog && (g_logfp != (FILE *)NULL) && g_logname[0])
{
NEWLINE(g_logfp);
(void)fputs(g_progname,g_logfp);
(void)fputs(": FATAL--",g_logfp);
(void)fputs(msg,g_logfp);
NEWLINE(g_logfp);
(void)fprintf(g_logfp,"Current TeX page counters: [%s]",tctos());
NEWLINE(g_logfp);
}
NEWLINE(stderr);
(void)fputs(g_progname,stderr);
(void)fputs(": FATAL--",stderr);
(void)fputs(msg,stderr);
NEWLINE(stderr);
(void)fprintf(stderr,"Current TeX page counters: [%s]",tctos());
NEWLINE(stderr);
NEWLINE(stderr);
g_errenc = 1; /* set global fatal exit code */
alldone();
}
void initglob() /* initialize global variables */
{
register int i; /* loop index */
register char* tcp; /* temporary character pointer */
/***********************************************************************
Set up masks such that rightones[k] has 1-bits at the right end of
the word from k .. 32-1, where bits are numbered from
left (high-order) to right (lower-order), 0 .. 32-1.
img_mask[k] has a 1-bit in position k, bits numbered as above.
power[k] is 1 << k, and gpower[k] is 2**k-1 (i.e. 1-bits in
low-order k positions). These 3 require only 32 entries each since
they deal with 32-bit words from the PK and GF font files.
These are set at run-time, rather than compile time to avoid (a)
problems with C preprocessors which sometimes do not handle large
constants correctly, and (b) host byte-order dependence.
***********************************************************************/
rightones[32-1] = 1;
for (i = 32-2; (i >= 0); --i)
rightones[i] = (rightones[i+1] << 1) | 1;
img_mask[31] = 1;
for (i = 30; i >= 0; --i)
img_mask[i] = img_mask[i+1] << 1;
power[0] = 1;
for (i = 1; i <= 31; ++i)
power[i] = power[i-1] << 1;
gpower[0] = 0; /* NB: we have gpower[0..32], not [0..31] */
for (i = 1; i <= 32; ++i)
gpower[i] = power[i-1] | gpower[i-1];
debug_code = 0;
runmag = STDMAG; /* default runtime magnification */
npage = 0;
copies = 1; /* number of copies of each page */
topmargin = 1.0; /* DVI driver standard default */
leftmargin = 1.0; /* DVI driver standard default */
subfile[0] = '\0';
#if VIRTUAL_FONTS
virt_font = FALSE;
#endif
/*
Copy default file fields into global variables, then replace by any
runtime environment variable definitions. We need not do this for
TOPS-20 and VAX VMS, since SUBPATH and FONTPATH are already
initialized to logical names which the operating system will
translate at file open time.
*/
(void)strcpy(helpcmd,"type \\tex\\dvi.hlp");
(void)strcpy(subpath,"\\TEX\\INPUTS\\");
(void)strcpy(subname,"TEXFONTS");
(void)strcpy(subext,".SUB");
(void)strcpy(fontpath,"\\TEX\\FONTS\\");
(void)strcpy(fontlist,"PK-GF-PXL");
if ((tcp = getenv("DVIHELP")) != (char *)NULL)
(void)strcpy(helpcmd,tcp);
if ((tcp = getenv("TEXINPUTS")) != (char *)NULL)
(void)strcpy(subpath,tcp);
if ((tcp = getenv("TEXFONTS")) != (char *)NULL)
(void)strcpy(fontpath,tcp);
if ((tcp = getenv("FONTLIST")) != (char *)NULL)
(void)strcpy(fontlist,tcp);
/* initialize the global vars ----- why do I have to do this ? */
g_errenc = 0; /* has an error been encountered? */
g_dolog = TRUE; /* allow log file creation */
g_logfp = (FILE*)NULL; /* log file pointer (for errors) */
plotfp = (FILE*)NULL; /* plot file pointer */
dvifp = (FILE*)NULL; /* DVI file pointer */
hfontptr = (struct font_entry *)NULL;
runlengthcode = FALSE; /* this is runtime option '-r' */
pfontptr = (struct font_entry *)NULL;
preload = TRUE; /* preload the font descriptions? */
fontfp = (FILE*)NULL; /* font file pointer */
quiet = FALSE; /* suppress status display when TRUE */
backwards = FALSE; /* print in backwards order */
bitmap = (unsigned long int *)NULL;
}
void option(optstr) /* process command-line option */
char *optstr; /* option string (e.g. "-m1500") */
{
register unsigned long int k; /* magnification */
register int value; /* converted digit string value */
register int m; /* loop index */
char *p; /* pointer into optstr */
int p1,p2,p3; /* temp values for sscanf() */
double fltmag; /* doubleing-point mag value */
typedef struct
{
char* envname;
char* envvar;
}
envstruct;
static envstruct envlist[] =
{ /* names and addresses of environment vars (alphabetical order) */
"type \\tex\\dvi.hlp", helpcmd,
"PK-GF-PXL", fontlist,
"TEXFONTS", fontpath,
"TEXINPUTS", subpath,
};
if (*optstr != '-')
return; /* return if this is not an option */
switch (*(optstr+1))
{
case 'a': /* A selects virtual font caching */
case 'A':
#if VIRTUAL_FONTS
virt_font = TRUE;
#endif
break;
case 'b': /* b selects backwards printing order */
case 'B':
backwards = TRUE;
break;
case 'c': /* c selects number of copies */
case 'C':
copies = (unsigned int) atoi(optstr+2);
copies = MAX(1,MIN(copies,256)); /* enforce reasonable limits */
break;
case 'd': /* d selects debug output */
case 'D':
debug_code |= (unsigned char)atoi(optstr+2);
break;
case 'e': /* e specifies ``environment'' variable definition */
case 'E': /* We ignore letter case since these come from */
/* the command line */
if (!(p = strrchr(optstr,'=')))
{
(void)usage(stderr);
(void)sprintf(message,
"option(): Bad switch [%s]--expected -eENVNAME=value",
optstr);
(void)fatal(message);
}
*p = '\0'; /* clobber "=" by string terminator */
for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m)
{
if (stricmp(optstr+2,envlist[m].envname) == 0)
{
(void)strcpy(envlist[m].envvar,p+1);
return;
}
}
(void)usage(stderr);
(void)sprintf(message,"option(): Bad switch [%s]--expected one of:",
optstr);
for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m)
{
(void)strcat(message," ");
(void)strcat(message,envlist[m].envname);
}
(void)fatal(message);
break;
case 'f': /* f specifies font substitution file */
case 'F':
(void)strcpy(subfile,optstr+2);
break;
case 'l': /* l prohibits logging of errors */
case 'L':
g_dolog = FALSE;
break;
case 'm': /* m selects alternate magnification */
case 'M':
/* Collect 2*value initially. Then if value is small, assume
user specified magstep value; magstep k means 1.2**k, where k
is integral, or half-integral. Otherwise, assume user has
specified pxl file magnification (1000 == 200dpi, 1500 ==
300dpi, etc.). */
if (strchr(optstr+2,'.') != (char *)NULL)
fltmag = (double)(2.0 * atof(optstr+2));
else
fltmag = (double)(2 * atoi(optstr+2));
if ((0.0 != fltmag) &&
(-30.0 <= fltmag) && (fltmag <= 30.0)) /* magstep 15 is limit */
{
if (fltmag < 0.0)
runmag = (unsigned long int)(0.5 +
(1.0/pow((double)sqrt(1.2),-fltmag))*(double)STDMAG);
else
runmag = (unsigned long int)(0.5 + pow((double)sqrt(1.2),fltmag)*
(double)STDMAG);
}
else
runmag = (unsigned long int)(0.5 + fltmag/2.0);
k = MAGSIZE(actfact(runmag)); /* rounded magnification */
if (k != runmag)
{
(void)sprintf(message,
"option(): Requested magnification %d not available.",
(int)runmag);
(void)warning(message);
runmag = k;
k = (unsigned long int) MAX(1,MIN(mag_index,(MAGTABSIZE-1)));
(void)sprintf(message,
" Magnification reset to nearest legal value %d in \
family ..%d..%d..%d..",
(int)runmag,(int)MAGSIZE(mag_table[k-1]),
(int)MAGSIZE(mag_table[k]),
(int)MAGSIZE(mag_table[k+1]));
(void)warning(message);
}
break;
case 'o':
case 'O': /* o selects output page range (-o# or -o#:# or -o#:#:#) */
p1 = p2 = p3 = 0;
value = (int)sscanf(optstr+2,"%d:%d:%d",&p1,&p2,&p3);
page_begin[npage] = p1;
page_end[npage] = p2;
page_step[npage] = p3;
switch (value)
{
case 1:
optstr++; /* point past "-" */
do /* skip over digit string */
{
optstr++;
}
while (isdigit(*optstr) || (*optstr == '-') || (*optstr == '+'));
if (*optstr) /* trash follows number */
{
(void)usage(stderr);
(void)sprintf(message,
"option(): %s is not a legal page number switch",optstr);
(void)fatal(message);
}
else /* had expected end-of-string */
page_end[npage] = (int)page_begin[npage];
page_step[npage] = 1;
break;
case 2: /* supply default step */
page_step[npage] = 1;
/* FALL THROUGH to case 3 for order check */
case 3: /* check for positive step */
page_step[npage] = ABS(page_step[npage]);
if (page_step[npage] == 0)
page_step[npage] = 1;
break;
default: /* illegal value */
(void)usage(stderr);
(void)sprintf(message,
"option(): %s is not a legal page number switch",optstr);
(void)fatal(message);
}
npage++;
break;
case 'p': /* p prohibits pre-font loading */
case 'P':
preload = FALSE;
break;
case 'q': /* q inhibits status display */
case 'Q':
quiet = TRUE;
break;
case 'r': /* r selects run-length coding of output */
case 'R':
runlengthcode = TRUE;
break;
case 'x':
case 'X':
leftmargin = inch(optstr+2);
break;
case 'y':
case 'Y':
topmargin = inch(optstr+2);
break;
default:
(void)usage(stderr);
(void)sprintf(message,"option(): %s is not a legal switch", optstr);
(void)fatal(message);
}
}
/* Return index (0,1,...) of substring in string */
/* or -1 if not found. Letter case is IGNORED. */
int strid2(string,substring)
char string[];
char substring[];
{
register int k; /* loop index */
register int limit; /* loop limit */
register char *s;
register char *sub;
limit = (int)strlen(string) - (int)strlen(substring);
for (k = 0; k <= limit; ++k)/* simple (and slow) linear search */
{
s = &string[k];
for (sub = &substring[0]; (toupper(*s) == toupper(*sub)) && (*sub); (++s, ++sub))
/* NO-OP */ ;
if (*sub == '\0') /* then all characters match */
return(k); /* success -- match at index k */
}
return(-1); /* failure */
}
/* (trailing zero counters are not printed) */
char * tctos() /* return pointer to (static) TeX page counter string */
{
register int k; /* loop index */
register int n; /* number of counters to print */
static char s[111]; /* 10 32-bit counters n.n.n... */
for (n = 9; (n > 0) && (tex_counter[n] == 0); --n)
/* NO-OP */;
s[0] = '\0';
for (k = 0; k <= n; ++k)
(void)sprintf(strrchr(s,'\0'),"%ld%s",
tex_counter[k],(k < n) ? "." : "");
return ((char *)&s[0]);
}
void usage(fp) /* print usage message to fp and return */
FILE *fp;
{
(void)fprintf(fp,"[TeX82 DVI Translator Version %s]",VERSION_NO);
NEWLINE(fp);
(void)fprintf(fp,"[%s]",DEVICE_ID);
NEWLINE(fp);
(void)sprintf(message,
"Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \
{-l} {-m#} {-o#:#:#} {-o#:#} {-o#} {-p} {-x#{units}} {-y#{units}} dvifile(s)",
g_progname);
(void)sprintf(message,
"Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \
{-l} {-m#} {-o#:#:#} {-o#:#} {-o#} {-p} {-r} {-t} {-x#{units}} {-y#{units}} \
{-z} dvifile(s)",
g_progname);
(void)fprintf(fp,message);
NEWLINE(fp);
(void)fprintf(fp,
"For documentation on this program, try the operating command(s):");
NEWLINE(fp);
(void)fprintf(fp,helpcmd);
NEWLINE(fp);
NEWLINE(fp);
}
void warning(msg) /* issue a warning */
char *msg; /* message string */
{
if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
{
g_logfp = fopen(g_logname,"w+");
DEBUG_OPEN(g_logfp,g_logname,"w+");
if (g_logfp != (FILE *)NULL)
{
(void)fprintf(stderr,"[Log file [%s] created]",g_logname);
NEWLINE(stderr);
}
}
if (g_dolog && (g_logfp != (FILE *)NULL) && g_logname[0])
{
NEWLINE(g_logfp);
(void)fputs(msg,g_logfp);
NEWLINE(g_logfp);
(void)fprintf(g_logfp,"Current TeX page counters: [%s]",tctos());
NEWLINE(g_logfp);
}
if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
{
(void)sprintf(message,"Cannot open log file [%s]",g_logname);
fatal(message);
}
NEWLINE(stderr);
(void)fputs(msg,stderr);
NEWLINE(stderr);
if (g_logname[0])
{
(void)fprintf(stderr,"Current TeX page counters: [%s]",tctos());
NEWLINE(stderr);
}
}